package com.lsh.oms.provider.service.after;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.dubbo.rpc.protocol.rest.support.ContentType;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import com.lsh.base.common.json.JsonUtils;
import com.lsh.base.common.model.CommonResult;
import com.lsh.oms.api.model.afterSales.RecreateAfterSalesRequestDto;
import com.lsh.oms.api.service.after.IAfterSalesRestService;
import com.lsh.oms.core.constant.ReturnCode;
import com.lsh.oms.core.enums.AfterSalesOrderStatusEnum;
import com.lsh.oms.core.enums.OrderStatus;
import com.lsh.oms.core.model.after.OrderAfterSales;
import com.lsh.oms.core.model.order.OrderHead;
import com.lsh.oms.core.model.query.MisOrderHeadForDetail;
import com.lsh.oms.core.mq.MessageProducer;
import com.lsh.oms.core.proxy.service.EsProxy;
import com.lsh.oms.core.service.aftersale.IAfterSalesService;
import com.lsh.oms.core.service.order.OrderQueryService;
import com.lsh.oms.core.service.query.FindOrderByMisService;
import com.lsh.oms.core.service.tool.ToolService;
import com.lsh.oms.provider.service.BaseService;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author xuzhan
 * on 16/10/10.
 */
@Service(protocol = "rest", validation = "true")
@Path("afterSales")
@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
@Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
@Deprecated
class AfterSalesRestServiceImpl extends BaseService implements IAfterSalesRestService {

    public static final Logger LOGGER = Logger.getLogger(AfterSalesRestServiceImpl.class);

    @Resource
    private IAfterSalesService afterSalesSerivce;

    @Resource
    private EsProxy esProxy;

    @Resource
    private FindOrderByMisService findOrderByMisService;

    @Autowired
    private OrderQueryService orderQueryService;

    @Value("${kafka.topic.of.after.sales:oms_after_sales}")
    private String topic;

    @Resource(name = "kafka.message.producer")
    private MessageProducer producer;

    @POST
    @Path("create")
    @Override
    public CommonResult<String> createAfterSalesBill(String model) {
        LOGGER.info("Request logSign : " + ToolService.getLogSign());
        String logSign = ToolService.getLogSign();
        LOGGER.info(logSign + ",createAfterSalesBill--  " + JsonUtils.obj2Json(model));
        try {
            OrderAfterSales vo = JSON.parseObject(model, OrderAfterSales.class);

            Long venderId = this.getVenderId();
            vo.setVenderId(venderId);

            boolean falg = checkParams(vo);
            if (!falg) {
                return new CommonResult<>(ReturnCode.REQUEST_FAIL, "参数异常.");
            }

            MisOrderHeadForDetail misOrderHeadForDetail = findOrderByMisService.getOrderHead(vo.getOrderCode());
            if (misOrderHeadForDetail == null) {
                return new CommonResult<>(ReturnCode.REQUEST_FAIL, "订单不存在");
            }
            Map<String, String> dbEntity = new HashMap<>();
            dbEntity.put("aftersalesCode", vo.getAftersalesCode() + "");
            OrderAfterSales aftNum = (OrderAfterSales) afterSalesSerivce.handleBussiness(JsonUtils.obj2Json(dbEntity));
            if (aftNum != null) {
                return new CommonResult<>(ReturnCode.REQUEST_FAIL, "此售后单号已存在。");
            }
            boolean status_flag = checkOrderStatus(misOrderHeadForDetail.getOrderStatus());
            if (!status_flag) {
                return new CommonResult<>(ReturnCode.REQUEST_FAIL, "订单状态不允许发起售后");
            }
            dbEntity.put("orderCode", vo.getOrderCode() + "");
            dbEntity.put("venderId", vo.getVenderId() + "");
            dbEntity.put("aftersalesStatus", vo.getAftersalesStatus() + "");
            int timestamp = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
            dbEntity.put("updateTime", timestamp + "");
            dbEntity.put("createTime", timestamp + "");
            OrderAfterSales result = (OrderAfterSales) afterSalesSerivce.handleBussiness(model);
            if (result != null) {
                if (result.getAftersalesCode().equals(vo.getAftersalesCode())) {
                    return new CommonResult<>(ReturnCode.REQUEST_FAIL, "售后单号重复");
                }
                afterSalesSerivce.handleBussiness(JsonUtils.obj2Json(dbEntity), 2);
            } else {
                LOGGER.info(JsonUtils.obj2Json(result));
                afterSalesSerivce.handleBussiness(JsonUtils.obj2Json(dbEntity), 1);
            }
            esProxy.editIndex(EsProxy.transformToOrderHeadForEs(vo.getOrderCode(), vo.getAftersalesStatus()), logSign);
            pushMQ(vo.getAftersalesCode());
        } catch (Exception e) {
            LOGGER.error(logSign + ",Full stack trace follows:", e);
            return new CommonResult<>(ReturnCode.REQUEST_FAIL, "fail");
        }

        return new CommonResult<>(ReturnCode.REQUEST_SUCCESS, "success");
    }

    /**
     * @param orderStatus
     * @return
     */
    private boolean checkOrderStatus(Integer orderStatus) {
        if (orderStatus == OrderStatus.ORDER_FINISH.getIndex()) {
            return true;
        }
        if (orderStatus == OrderStatus.ORDER_SIGN.getIndex()) {
            return true;
        }
        return false;
    }

    /**
     * @param vo
     * @return
     */
    private boolean checkParams(OrderAfterSales vo) {
        List<Integer> statusList = new ArrayList<>();
        for (AfterSalesOrderStatusEnum afoStatus : AfterSalesOrderStatusEnum.values()) {
            statusList.add(afoStatus.getValue());
        }
        if (!statusList.contains(vo.getAftersalesStatus())) {
            return false;
        }
        //无效
        if (vo.getOrderCode() == null) {
            return false;
        }
        if (StringUtils.isBlank(vo.getAftersalesCode())) {
            return false;
        }

        return true;
    }

    @POST
    @Path("update")
    @Override
    public CommonResult<String> updateAfterSalesBillStatus(String model) {
        LOGGER.info("start !Request logSign : " + ToolService.getLogSign());
        String logSign = ToolService.getLogSign();
        LOGGER.info(logSign + ",updateAfterSalesBillStatus--  " + model);
        CommonResult<String> resp = new CommonResult<>();
        try {
            OrderAfterSales vo = JSON.parseObject(model, OrderAfterSales.class);

            boolean falg = checkParams(vo);
            if (!falg) {
                resp.setCode(ReturnCode.REQUEST_FAIL);
                resp.setMessage("参数异常.");
                LOGGER.info("end !Request logSign : " + logSign + ",return:" + JsonUtils.obj2Json(resp));
                return resp;
            }
            if (vo.getReturnWarehouseStatus() == null) {
                resp.setCode(ReturnCode.REQUEST_FAIL);
                resp.setMessage("参数异常.");
                LOGGER.info("end !Request logSign : " + logSign + ",return:" + JsonUtils.obj2Json(resp));
                return resp;
            }

            MisOrderHeadForDetail misOrderHeadForDetail = findOrderByMisService.getOrderHead(vo.getOrderCode());
            if (misOrderHeadForDetail == null) {
                return new CommonResult<>(ReturnCode.REQUEST_FAIL, "订单不存在");
            }
            Map<String, String> dbEntity = new HashMap<String, String>();
            dbEntity.put("orderCode", vo.getOrderCode() + "");
            OrderAfterSales result = (OrderAfterSales) afterSalesSerivce.handleBussiness(JsonUtils.obj2Json(dbEntity));
            if (result == null) {
                resp.setCode(ReturnCode.REQUEST_FAIL);
                resp.setMessage("该订单没有关联售后业务，请核实。");
                LOGGER.info("end !Request logSign : " + logSign + ",return:" + JsonUtils.obj2Json(resp));
                return resp;
            }
            if (!result.getAftersalesCode().equals(vo.getAftersalesCode())) {
                resp.setCode(ReturnCode.REQUEST_FAIL);
                resp.setMessage("该订单关联的售后单号不是" + vo.getAftersalesCode());
                LOGGER.info("end !Request logSign : " + logSign + ",return:" + JsonUtils.obj2Json(resp));
                return resp;
            }

            dbEntity.put("aftersalesCode", vo.getAftersalesCode() + "");
            dbEntity.put("aftersalesStatus", vo.getAftersalesStatus() + "");
            int timestamp = (int) TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
            dbEntity.put("updateTime", timestamp + "");
            afterSalesSerivce.handleBussiness(JsonUtils.obj2Json(dbEntity), 2);

            esProxy.editIndex(EsProxy.transformToOrderHeadForEs(vo.getOrderCode(), vo.getAftersalesStatus()), logSign);
            pushMQ(vo.getAftersalesCode());
        } catch (Exception e) {
            LOGGER.error(logSign + ",Full stack trace follows:", e);
            resp.setCode(ReturnCode.REQUEST_FAIL);
            resp.setMessage("fail");
            LOGGER.info("end !Request logSign : " + logSign + ",return:" + JsonUtils.obj2Json(resp));
            return resp;
        }
        resp.setCode(ReturnCode.REQUEST_SUCCESS);
        resp.setMessage("success");
        LOGGER.info("end !Request logSign : " + logSign + ",return:" + JsonUtils.obj2Json(resp));
        return resp;

    }

    @POST
    @Path("recreate")
    @Override
    public CommonResult<String> recreateAfterSalesBill(RecreateAfterSalesRequestDto recreateAfterSalesRequestDto) {
        String logSign = ToolService.getLogSign();
        long startTime = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        sb.append("[Recreate afterSalesBill][").append(logSign).append("]");
        String prefix = sb.toString();
        LOGGER.info(prefix + "[start][params:" + JSON.toJSONString(recreateAfterSalesRequestDto) + "]");

        try {
            Long orderCode = recreateAfterSalesRequestDto.getOrderCode();
            OrderHead orderHead = orderQueryService.findByCode(orderCode, false, false);
            if (orderHead == null) {
                long endTime = System.currentTimeMillis();
                String message = "订单不存在.订单号:" + orderCode;
                LOGGER.error(prefix + "[" + (endTime - startTime) + "ms][" + message + "]");
                return new CommonResult<String>(ReturnCode.ORDER_IS_NOT_EXIST, message);
            }
            OrderStatus orderStatus = OrderStatus.indexOf(orderHead.getOrderStatus().intValue());
            if (orderStatus != OrderStatus.ORDER_SIGN && orderStatus != OrderStatus.ORDER_FINISH) {
                long endTime = System.currentTimeMillis();
                String message = "订单状态不允许操作.当前订单状态:" + orderStatus.getName();
                LOGGER.error(prefix + "[" + (endTime - startTime) + "ms][" + message + "]");
                return new CommonResult<String>(ReturnCode.ORDER_STATUS_ERROR, message);
            }

            List<OrderAfterSales> list = this.afterSalesSerivce.loadAfterSales(orderCode);
            if (list == null || list.size() <= 0) {
                long endTime = System.currentTimeMillis();
                String message = "没有查询到对应的售后.订单号:" + orderCode;
                LOGGER.error(prefix + "[" + (endTime - startTime) + "ms][" + message + "]");
                return new CommonResult<String>(ReturnCode.REQUEST_FAIL, message);
            }
            OrderAfterSales orginAfterSales = this.findMaxIdAfterSales(list);
            AfterSalesOrderStatusEnum afterSalesOrderStatusEnum =
                    AfterSalesOrderStatusEnum.indexOf(orginAfterSales.getAftersalesStatus().intValue());
            if (afterSalesOrderStatusEnum != AfterSalesOrderStatusEnum.TO_PICKING) {
                long endTime = System.currentTimeMillis();
                String message = "当前售后状态不允许重新生成售后单.当前售后状态:" + afterSalesOrderStatusEnum.getValue();
                LOGGER.error(prefix + "[" + (endTime - startTime) + "ms][" + message + "]");
                return new CommonResult<String>(ReturnCode.REQUEST_FAIL, message);
            }

            OrderAfterSales afterSales = this.buildAfterSales(orginAfterSales, recreateAfterSalesRequestDto);
            boolean isSuccess = this.afterSalesSerivce.recreateAfterSales(list, afterSales);
            if (!isSuccess) {
                long endTime = System.currentTimeMillis();
                String message = "插入数据库失败!";
                LOGGER.error(prefix + "[" + (endTime - startTime) + "ms][" + message + "]");
                return new CommonResult<String>(ReturnCode.REQUEST_FAIL, message);
            }
        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            String message = "Error message:" + e.getMessage();
            LOGGER.error(prefix + "[" + (endTime - startTime) + "ms][" + message + "]");
            LOGGER.error(e.getMessage(), e);
            return new CommonResult<String>(ReturnCode.SYS_ERROR, e.getMessage());
        }

        long endTime = System.currentTimeMillis();
        LOGGER.info(prefix + "[" + (endTime - startTime) + "ms][end]");
        return new CommonResult<String>(ReturnCode.REQUEST_SUCCESS, "success.");
    }

    /**
     * @param list
     * @return
     */
    private OrderAfterSales findMaxIdAfterSales(List<OrderAfterSales> list) {
        OrderAfterSales afterSales = list.get(0);
        for (OrderAfterSales item : list) {
            if (item.getId().longValue() > afterSales.getId().longValue()) {
                afterSales = item;
            }
        }
        return afterSales;
    }

    /**
     * @param orginAfterSales
     * @param requestDto
     * @return
     */
    private OrderAfterSales buildAfterSales(OrderAfterSales orginAfterSales, RecreateAfterSalesRequestDto requestDto) {
        OrderAfterSales afterSales = new OrderAfterSales();
        afterSales.setOrderCode(orginAfterSales.getOrderCode());
        afterSales.setAftersalesOrderCode(orginAfterSales.getAftersalesOrderCode());
        afterSales.setAftersalesCode(requestDto.getAfterSalesCode());
        afterSales.setAftersalesType(requestDto.getAfterSalesType());
        afterSales.setAftersalesStatus(orginAfterSales.getAftersalesStatus());
        afterSales.setReturnWarehouseStatus(orginAfterSales.getReturnWarehouseStatus());
        return afterSales;
    }

    private void pushMQ(String afterSalesCode) {
        OrderAfterSales afterSales = afterSalesSerivce.findOne(afterSalesCode);
        if (afterSales != null) {
            producer.send(topic, ImmutableMap.of("head", afterSales));
        }
    }
}
